/*
 * All rights Reserved, Designed By cloudland Copyright(C) 2010-2014
 *
 * fileName:  Configuration.java
 * author:  lei
 * Company:  Cloudland Studio
 * Createdate:  2013-9-19 下午9:57:33
 *   
 * Modification  History:
 *     Date           Author        Version        
 * -------------------------------------------
 * 2013-9-19          Lei            1.0        
 *
 * Why & What is modified:
 * 1.0: 文件创建
 */
package org.cloudland.search.config;

import java.util.List;

import org.apache.log4j.Logger;
import org.cloudland.search.config.support.ConstructorParameter;
import org.cloudland.search.config.support.DocumentDescImpl;
import org.cloudland.search.config.support.DocumentDescImpl.DocumentDescEntity;
import org.cloudland.search.config.support.FieldDescEntity;
import org.cloudland.search.exception.ConstantsException;
import org.cloudland.search.exception.SearchException;

import com.ggzone.basic.io.XMLResolve;
import com.ggzone.basic.io.XMLResolve.XMLEntry;

 /**
 * <pre> 
 * TODO 请充分描述该类提供的作用, 或与其他类会有关联的使用。
 * 使用 {@link java.lang.Object#toString()}, 或者 {@link java.lang.Character Character} 等标签
 * </pre>
 * @ClassName  Configuration
 * @author  lei
 * @version  %I%, %G%
 * @see  
 * @since   JDK1.6
 *
 */
public class Configuration {

	private Logger logger = Logger.getLogger(Configuration.class);
    
    private XMLResolve xmlResolve;
    
    /**
     * 
     * 默认空参构造函数
     */
    protected Configuration(){}
    
    
    public Configuration(String configPath)
    {
       if (configPath==null || configPath.length()<1)
       {
           logger.warn("传递的配置文件路径为空，无法获取对应的Configuration实例");
           throw new SearchException(ConstantsException.SEARCH_CONFIG_0001);
       }
        
        xmlResolve = XMLResolve.doInstance(configPath);
        if (xmlResolve == null)
        {
            logger.warn("获取对应的Configuration实例时，读取配置文件失败");
            throw new SearchException(ConstantsException.SEARCH_CONFIG_0007);
        }
    }
    
    /**
     * 
     *@description: 获取搜索的配置文档信息
     *@return 配置文档信息的数组
     */
    @SuppressWarnings("unchecked")
    public IDocumentDesc[] getDocumentDesc()
    {
        IDocumentDesc[] result = null;
        try
        {
                List<XMLEntry> elementList = xmlResolve.getCurrentElement("searches/search");
                if (elementList!=null && elementList.size()>0)
                {
                    result = new  IDocumentDesc[elementList.size()];
                    XMLEntry tempEntity = null;
                    DocumentDescImpl documentDesc = null;
                    DocumentDescEntity documentEntity = null;
                    FieldDescEntity fieldEntity = null;
                    ConstructorParameter parameters = null;
                    List<XMLEntry> childList = null;
                    
                    for (int i=0; i<elementList.size(); i++)
                    {
                       tempEntity =  elementList.get(i);
                       documentDesc = new DocumentDescImpl();
                       documentEntity = documentDesc.new DocumentDescEntity();
        
                       childList = tempEntity.getChild("name");//设置搜索配置的服务名称
                       if (childList!=null && childList.size()>0)
                       {
                           documentEntity.setSearchName(childList.get(0).getText());
                       }
                       
                       childList = tempEntity.getChild("analyzer/parameter");//设置索引使用的分析器参数
                       if (childList!=null && childList.size()>0)
                       {
                           @SuppressWarnings("rawtypes")
                           Class paraType = null;
                           for (XMLEntry temp : childList)
                           {
                               parameters = new ConstructorParameter();
                               /**下面这段代码需要改造，现在是不正确的*开始**/
                               if(temp.getAttribute("enum-type")!=null)
                               {
                                   paraType = Class.forName(temp.getAttribute("enum-type")); 
                                   parameters.setParameterType(paraType);
                               
                                   parameters.setParameterValue((Object)Enum.valueOf(paraType, temp.getAttribute("value")));
                               }
                               else
                               {
                                   paraType = Class.forName(temp.getAttribute("type")); 
                                   parameters.setParameterType(paraType);
                               
                                   parameters.setParameterValue(temp.getAttribute("value"));
                               }
                               /**下面这段代码需要改造，现在是不正确的*结束**/
                               documentEntity.getParameterList().add(parameters);//将索引项加入到索引配置中
                               
                           }//end for
                       }
                       
                       childList = tempEntity.getChild("analyzer/name");//设置索引使用的分析器
                       if (childList!=null && childList.size()>0)
                       {
                           documentEntity.setSearchAnalyzer(childList.get(0).getText());
                       }
                       
                       childList = tempEntity.getChild("position");//设置索引位置
                       if (childList!=null && childList.size()>0)
                       {
                           documentEntity.setIndexPosition(childList.get(0).getText());
                       }
                       
                       childList = tempEntity.getChild("fields/field");//设置索引项配置
                       if (childList!=null && childList.size()>0)
                       {
                           int count = 0;
                           for (XMLEntry temp : childList)
                           {
                               fieldEntity = new FieldDescEntity();
                               fieldEntity.setFieldAnalyzer(temp.getAttribute("isAnalyzer"));
                               fieldEntity.setFieldGrade(temp.getAttribute("isGrade"));
                               fieldEntity.setFieldIndex(temp.getAttribute("isIndex"));
                               fieldEntity.setFieldMapping(temp.getAttribute("fieldMapping"));
                               fieldEntity.setFieldName(temp.getAttribute("fieldName"));
                               fieldEntity.setFieldStore(temp.getAttribute("isStore"));
                               fieldEntity.setFieldType(temp.getAttribute("fieldType"));
                               fieldEntity.setFieldWeight(temp.getAttribute("weight"));
                               if (temp.getAttribute("primaryKey") != null)
                               {
                                   if (count > 0)
                                   {
                                       logger.error(documentEntity.getSearchName()+" 配置的索引域中出现多个primarykey");
                                       throw new SearchException(ConstantsException.SEARCH_CONFIG_0009);
                                   }
                                   if ("true".equals(temp.getAttribute("primaryKey").toLowerCase()))
                                   {
                                       count++;
                                   }
                                   fieldEntity.setPrimaryKey(temp.getAttribute("primaryKey"));
                               }
                               
                               documentEntity.getFieldDescList().add(fieldEntity);//将索引项加入到索引配置中
                               
                           }//end for
                           if (count < 1)
                           {
                               logger.error(documentEntity.getSearchName()+" 配置的索引域中没有找到primarykey");
                               throw new SearchException(ConstantsException.SEARCH_CONFIG_0010);
                           }
                       }
                       else
                       {
                           logger.error(documentEntity.getSearchName()+"配置文件中没有找到配置的索引域field");
                           throw new SearchException(ConstantsException.SEARCH_CONFIG_0011);
                       }
                       
                       documentDesc.setDocumentDescEntity(documentEntity);//对外接口提供数据
                       result[i] = documentDesc;
                    }//end for
                    
                }//end if
        }
        catch (SearchException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            logger.error("Configuration获取搜索的配置文档信息产生错误", e);
            throw new SearchException(ConstantsException.SEARCH_CONFIG_0002);
        }
        
        return result;
        
    }
    
}
